package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.OssTemplate;
import com.itheima.domain.db.*;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.RecommendUserService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author zsk
 * @create 2022-03-17-16:13
 */
@Component
public class MovementManager {

    @DubboReference
    private MovementService movementService;

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private UserInfoService userInfoService;

    @DubboReference
    private CommentService commentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private RecommendUserService recommendUserService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MQMovementManager mqMovementManager;

    //发表动态
    public void saveMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //获取线程内userId
        Long userId = UserHolder.get().getId();

        //将动态图片上传到阿里云Oss
        //声明存储图片地址集合
        List<String> medias = new ArrayList<>();
        //非空判断
        if (ArrayUtil.isNotEmpty(imageContent)){
            //遍历
            for (MultipartFile multipartFile : imageContent) {
                //上传
                String url = ossTemplate.upload(multipartFile.getOriginalFilename(),
                        multipartFile.getInputStream());
                //存储图片到图片集合中
                medias.add(url);
            }
        }
        //封装动态实体
        movement.setId(new ObjectId());//设置动态id
        movement.setUserId(userId);//当前用户id
        movement.setMedias(medias);//图片集合
        movement.setState(0);//状态需要审核
        movement.setCreated(System.currentTimeMillis());//发布时间
        movement.setSeeType(1);//公开
        //调用rpc发布动态
        movementService.saveMovement(movement);

        //将动态id发送到mq
        rabbitTemplate.convertAndSend("tanhua.movement.log",movement.getId());

        //动态推荐
        mqMovementManager.sendMovement(userId,movement.getId(),MQMovementManager.MOVEMENT_PUBLISH);


    }

    //查看我的动态
    public ResponseEntity findByMovementPage(Long userId, Integer pageNum, Integer pageSize) {
        //调用rpc查询动态分页
        PageBeanVo pageBeanVo = movementService.findByMovementPage(userId,pageNum,pageSize);

        //声明movementVo
        List<MovementVo> voList = new ArrayList<>();
        //取出返回结果
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        //非空判断
        if (CollectionUtil.isNotEmpty(movementList)){
            //遍历
            for (Movement movement : movementList) {

                MovementVo vo = new MovementVo();

                //先查询用户信息
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //先封装userInfo
                vo.setUserInfo(userInfo);

                //封装用户动态信息movement
                vo.setMovement(movement);

                //判断是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toHexString()))){
                    vo.setHasLiked(1);
                }
                //添加到movementVo集合对象中
                voList.add(vo);
            }
        }

        //将voList添加到PageBeanVo分页对象中
        pageBeanVo.setItems(voList);

        //返回数据
        return ResponseEntity.ok(pageBeanVo);
    }

    //获取好友动态
    public ResponseEntity findByFriendMovement(Integer pageNum, Integer pageSize) {

        //获取线程内UserId
        Long userId = UserHolder.get().getId();

        //根据三个条件查询动态详情
        PageBeanVo pageBeanVo = movementService.findByFriendMovement(userId,pageNum,pageSize);

        //新建一个MovementVo集合对象存储动态详情
        List<MovementVo> voList = new ArrayList<>();

        //查询当页动态信息
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        //非空判断
        if (CollectionUtil.isNotEmpty(movementList)){
            for (Movement movement : movementList) {

                MovementVo vo = new MovementVo();

                //根据movement里的userId查询UserInfo信息
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //封装voList信息
                vo.setUserInfo(userInfo);
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toHexString()))){
                    vo.setHasLiked(1);
                }

                //后封装movement信息
                vo.setMovement(movement);

                //最后存储到movementVo集合中
                voList.add(vo);
            }
        }

        //将voList集合对象存储到pageBeanVo中
        pageBeanVo.setItems(voList);

        //返回前端pageBeanVo
        return ResponseEntity.ok(pageBeanVo);

    }

    //查询推荐动态
    public ResponseEntity findRecommendMovementByPage(Integer pageNum, Integer pageSize) {

        //获取线程内UserId
        Long userId = UserHolder.get().getId();

        //调用rpc查询分页结果
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(userId,pageNum,pageSize);

        //创建一个存储动态详细信息的集合
        List<MovementVo> movementVoList = new ArrayList<>();

        //获取当前页数据
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        //非空判断
        if (CollectionUtil.isNotEmpty(movementList)){
            for (Movement movement : movementList) {
                //根据id查询用户信息列表
                UserInfo userInfo = userInfoService.findById(movement.getUserId());
                //组装MovementVo信息
                MovementVo vo = new MovementVo();
                vo.setUserInfo(userInfo);

                //后封装movement对象
                vo.setMovement(movement);

                //判断是否点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,movement.getId().toHexString()))){
                    vo.setHasLiked(1);
                }

                //存储到movementVoList集合中
                movementVoList.add(vo);

            }
        }
        //最后封装到pageBeanVo中
        pageBeanVo.setItems(movementVoList);
        //返回结果
        return ResponseEntity.ok(pageBeanVo);

    }

    //设置点赞
    public ResponseEntity movementLike(String publishId) {

        //获取线程内userId
        Long userId = UserHolder.get().getId();
        //调用publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));
        //封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());//点赞时间
        comment.setPublishId(movement.getId());//动态id
        comment.setCommentType(1);//操作类型
        comment.setUserId(userId);//操作人
        comment.setPublishUserId(movement.getUserId());//动态发布人id
        //设置访问记录
        Visitor visitor = new Visitor();
        visitor.setDate(comment.getCreated());//访问时间
        visitor.setUserId(movement.getUserId());//我的id
        visitor.setVisitorUserId(userId);//来访用户id
        visitor.setFrom("首页");
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        //保存访问记录
        movementService.saveVisitor(visitor);
        //调用rpc保存,返回点赞数量
        Integer likeCount = commentService.saveComment(comment);
        //向redis中存储点赞标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,publishId),"1");
        //返回点赞数量
        return ResponseEntity.ok(likeCount);


    }

    //取消点赞
    public ResponseEntity movementDeleteLike(String publishId) {

        //获取线程内UserId
        Long userId = UserHolder.get().getId();

        //调用rpc删除
        Integer likeCount = commentService.removeComment(userId, new ObjectId(publishId), 1);

        //从Redis中删除点赞标记(根据键删除值)
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE,userId,publishId));

        //返回点赞数量
        return ResponseEntity.ok(likeCount);

    }

    //设置喜欢
    public ResponseEntity movementLove(String publishId) {

        //获取线程内userId
        Long userId = UserHolder.get().getId();

        //根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));

        //封装comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());//发表时间
        comment.setPublishId(movement.getId());//动态id
        comment.setCommentType(3);//喜欢类型
        comment.setUserId(userId);//操作人
        comment.setPublishUserId(movement.getUserId());// 动态发布人id

        //设置访问记录
        Visitor visitor = new Visitor();
        visitor.setDate(comment.getCreated());//访问时间
        visitor.setUserId(movement.getUserId());//我的id
        visitor.setVisitorUserId(userId);//来访用户id
        visitor.setFrom("首页");
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        //保存访问记录
        movementService.saveVisitor(visitor);

        //调用rpc保存
        Integer loveCount = commentService.saveComment(comment);

        //往Redis中存入标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,userId,publishId),"1");

        //返回喜欢数据
        return ResponseEntity.ok(loveCount);


    }

    //取消喜欢
    public ResponseEntity movementDeleteLove(String publishId) {
        //获取线程内UserId
        Long userId = UserHolder.get().getId();

        //调用rpc删除
        Integer loveCount = commentService.removeComment(userId, new ObjectId(publishId), 3);

        //从Redis中删除标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE,userId,publishId));

        //返回数据
        return ResponseEntity.ok(loveCount);
    }

    //展示单条动态
    public ResponseEntity findMovementVoById(String publishId) {
        //根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));

        //封装movementVo
        MovementVo vo = new MovementVo();
        UserInfo userInfo = userInfoService.findById(movement.getUserId());

        //先封装UserInfo信息
        vo.setUserInfo(userInfo);

        //再封装movement信息
        vo.setMovement(movement);

        //返回前端结果
        return ResponseEntity.ok(vo);

    }

    //展示动态评论
    public ResponseEntity findCommentVoByPage(String publishId, Integer pageNum, Integer pageSize) {

        //调用rpc查询评论分页
        PageBeanVo pageBeanVo = commentService.findCommentByPage(new ObjectId(publishId),2,pageNum,pageSize);

        //声明CommentVoList集合对象
        List<CommentVo> voList = new ArrayList<>();

        //查询当前页数据
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();

        //非空判断
        if (CollectionUtil.isNotEmpty(commentList)){
            for (Comment comment : commentList) {

                CommentVo vo = new CommentVo();

                //查询UserInfo对象
                UserInfo userInfo = userInfoService.findById(comment.getUserId());
                //封装到commentVo对象中
                vo.setAvatar(userInfo.getAvatar());//封装头像信息
                vo.setNickname(userInfo.getNickname());//昵称
                //后封装comment对象
                vo.setId(comment.getId().toHexString());//封装id
                vo.setContent(comment.getContent());
                vo.setCreateDate(DateUtil.formatDate(new Date(comment.getCreated())));//发表评论的时间
                //封装到集合对象中
                voList.add(vo);
            }
        }

        //存储到Page集合对象中
        pageBeanVo.setItems(voList);

        //返回前端pageBeanVo
        return ResponseEntity.ok(pageBeanVo);
    }

    //发表评论
    public void movementComment(String publishId, String content) {

        //获取线程UserId
        Long userId = UserHolder.get().getId();

        //根据publishId查询动态详情
        Movement movement = movementService.findById(new ObjectId(publishId));

        //封装Comment对象
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());//当前时间
        comment.setPublishId(new ObjectId(publishId));//动态id
        comment.setCommentType(2);//类型
        comment.setUserId(userId);
        comment.setPublishUserId(movement.getUserId());// 动态发布人id
        comment.setContent(content);//评论内容

        //设置访问记录
        Visitor visitor = new Visitor();
        visitor.setDate(comment.getCreated());//访问时间
        visitor.setUserId(movement.getUserId());//我的id
        visitor.setVisitorUserId(userId);//来访用户id
        visitor.setFrom("首页");
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        //保存访问记录
        movementService.saveVisitor(visitor);

        //调用rpc保存
        commentService.saveComment(comment);

    }

}
